package com.keta.foundation.controller;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.keta.foundation.entity.Role;
import com.keta.foundation.entity.User;
import com.keta.foundation.entity.UserRole;
import com.keta.foundation.log.Log;
import com.keta.foundation.log.LogUtil;
import com.keta.foundation.service.RoleService;
import com.keta.foundation.service.UserRoleService;
import com.keta.foundation.service.UserService;
import com.keta.foundation.shiro.ShiroUser;
import com.keta.foundation.util.dwz.AjaxObject;
import com.keta.foundation.util.dwz.Page;

@Controller
@RequestMapping("/user")
public class UserController {

	private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

	private final static String USER_LIST = "user/list";
	private final static String USER_CREATE = "user/create";
	private final static String USER_EDIT = "user/edit";
	private final static String USER_ASSIGN = "user/assign_role";
	private final static String USER_UPDATEPWD= "user/update_pwd";
	private final static String USER_UPDATEINFO= "user/updateInfo";

	@Autowired
	private UserService userService;

	@Autowired
	private UserRoleService userRoleService;

	@Autowired
	private RoleService roleService;

	@RequiresPermissions("User:view")
	@RequestMapping("/list")
	public String list(Page page, Model model) {

		List<User> userList = userService.getAll(page);

		model.addAttribute("page", page);
		model.addAttribute("userList", userList);
		return USER_LIST;
	}

	@RequiresPermissions("User:create")
	@RequestMapping(value = "/create", method = RequestMethod.GET)
	public String preCreate() {
		return USER_CREATE;
	}

	@ResponseBody
	@RequestMapping(value = "/create", method = RequestMethod.POST)
	@Log(message = "添加了用户:{0}")
	@RequiresPermissions("User:create")
	public String create(@Valid User user) {

		userService.saveOrUpdate(user);
		LogUtil.putArgs(new Object[] { user.getUsername() });
		return AjaxObject.newOk("用户添加成功!").toString();
	}

	@RequiresPermissions("User:edit")
	@RequestMapping(value = "/edit/{userId}", method = RequestMethod.GET)
	public String preEdit(@PathVariable Long userId, Model model) {
		User user = userService.get(userId);
		model.addAttribute("user", user);
		return USER_EDIT;
	}

	@ResponseBody
	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	@Log(message = "修改了用户:{0}")
	@RequiresPermissions("User:edit")
	public String edit(@Valid User user) {

		userService.saveOrUpdate(user);
		LogUtil.putArgs(new Object[] { user.getUsername() });
		return AjaxObject.newOk("用户修改成功!").toString();
	}

	@ResponseBody
	@RequestMapping(value = "/delete", method = RequestMethod.POST)
	@Log(message = "删除了用户，Id为:{0}")
	@RequiresPermissions("User:delete")
	public String delete(Long[] ids) {

		for (Long id : ids) {
			userService.delete(id);
			logger.info("删除了用户" + id);
		}

		LogUtil.putArgs(new Object[] { Arrays.toString(ids) });
		return AjaxObject.newOk("删除用户成功!").setCallbackType("").toString();
	}

	@Log(message = "重置密码{0}")
	@RequiresPermissions("User:restPwd")
	@RequestMapping(value = "/restPwd", method = RequestMethod.POST)
	public @ResponseBody String restPwd(Long[] ids) {
		String logInfo = "";
		for (Long id : ids) {
			User user = userService.get(id);
			userService.restPassword(user, "123456");
			logger.info("重置了用户" + user.getUsername() + "的密码！");
			logInfo += user.getUsername() + "   ";
		}

		LogUtil.putArgs(new Object[] { logInfo });
		return AjaxObject.newOk("重置密码成功!").setCallbackType("").toString();
	}
	
	@RequiresPermissions("User:updatePwd")
	@RequestMapping(value = "/updatePwd", method = RequestMethod.GET)
	public String preUpdatePwd() {
		return USER_UPDATEPWD;
	}
	
	@Log(message = "用户{0}修改了密码")
	@RequiresPermissions("User:updatePwd")
	@RequestMapping(value = "/updatePwd", method = RequestMethod.POST)
	public @ResponseBody String updatePwd(String oldPwd,String newPwd) {
		ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		boolean  validRet =  userService.validPasswrod(shiroUser.getUser(), oldPwd);
		if(validRet){
			userService.restPassword(shiroUser.getUser(), newPwd);
			LogUtil.putArgs(new Object[] { shiroUser.getLoginName() });
			return AjaxObject.newOk("密码修改成功!").setCallbackType("").toString();
		}else{
			return AjaxObject.newError("原密码不匹配，无法修改密码!").setCallbackType("").toString();
		}		
	}

	@Log(message = "{0}")
	@RequiresPermissions("User:updateStatus")
	@RequestMapping(value = "/updateStatus", method = RequestMethod.POST)
	public @ResponseBody String updateStatus(Long[] ids) {
		String logInfo = "";
		for (Long id : ids) {
			User user = userService.get(id);
			userService.updateStatus(user);
			logger.info("更新了" + user.getUsername() + "的状态！");
			logInfo +="更新了" + user.getUsername() + "的状态为"+user.getStatus() + "  ";
		}
		LogUtil.putArgs(new Object[] { logInfo });
		
		return AjaxObject.newOk("更新状态成功!").setCallbackType("").toString();
	}
	
	@RequiresPermissions("User:updateInfo")
	@RequestMapping(value = "/updateInfo", method = RequestMethod.GET)
	public  String preUpdateInfo(Model model) {
		ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		model.addAttribute("user", userService.get(shiroUser.getUser().getId()));
		return USER_UPDATEINFO;
	}
	
	@Log(message = "用户{0}修改了个人信息")
	@RequiresPermissions("User:updateInfo")
	@RequestMapping(value = "/updateInfo", method = RequestMethod.POST)
	public @ResponseBody String updateInfo(@Valid User user) {
		
		ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		User saveUser = shiroUser.getUser();
		saveUser.setRealname(user.getRealname());
		saveUser.setEmail(user.getEmail());
		saveUser.setPhone(user.getPhone());
		userService.saveOrUpdate(user);
		LogUtil.putArgs(new Object[] { shiroUser.getLoginName() });
		
		return AjaxObject.newOk("修改个人信息成功!").setCallbackType("").toString();
	}
	
	

	@RequiresPermissions("User:assign")
	@RequestMapping(value = "/assign/{userId}")
	public String assign(@PathVariable Long userId, Model model) {

		User user = userService.get(userId);

		List<Role> allRole = roleService.getAll();
		List<UserRole> userRoles = userRoleService.getUserRole(user);
		List<Role> subRoles = new ArrayList<Role>();
		for (Role role : allRole) {
			boolean flag = false;
			for (UserRole userRole : userRoles) {
				if (role.getId() == userRole.getRole().getId()) {
					flag = true;
				}
			}
			if (flag == false) {
				subRoles.add(role);
			}
		}

		model.addAttribute("user", user);
		model.addAttribute("userRoles", userRoles);
		model.addAttribute("subRoles", subRoles);
		return USER_ASSIGN;
	}

	@Log(message = "向{0}用户分配了{1}角色")
	@RequiresPermissions("User:assign")
	@RequestMapping(value = "/assignRole", method = RequestMethod.POST)
	public @ResponseBody String assignRole(UserRole userRole, Model model) {

		userRoleService.save(userRole);

		User user = userService.get(userRole.getUser().getId());
		Role role = roleService.get(userRole.getRole().getId());
		LogUtil.putArgs(new Object[] { user.getUsername(), role.getName() });
		return AjaxObject.newOk("").toString();
	}

	@Log(message = "撤销了{0}用户的{1}角色")
	@RequiresPermissions("User:assign")
	@RequestMapping(value = "/undoRole", method = RequestMethod.POST)
	public @ResponseBody String undoRole(UserRole userRole, Model model) {
		userRole = userRoleService.get(userRole.getId());
		userRoleService.delete(userRole);

		LogUtil.putArgs(new Object[] { userRole.getUser().getUsername(), userRole.getRole().getName() });
		return AjaxObject.newOk("").toString();
	}

}
